using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Diagnostics;

namespace WozLib.WozObjects
{
  
  public static class ServerObjectRegistry
  {
    private static Dictionary<long,IServerObject> _ServerObjects = new Dictionary<long,IServerObject>();

    private static long _NextServerID = 0;

    // just a lock object for _NextServerID
    private static List<IServerObject> dummy = new List<IServerObject>();

    static ServerObjectRegistry()
    {
    }

    public static void RegisterObject(IServerObject serverObject)
    {
      long id = long.MinValue;

      // lock on Server Object Dictionary so we can prevent handing out duplicate IDs
      lock (dummy)
      {
        // Get the next ID
        id = _NextServerID;

        // Increment the next ID
        _NextServerID++;
      }

      RegisterObject(serverObject, id);

      Debug.WriteLine("Registered " + serverObject.ToString() + " with ID: " + id.ToString());
    }

    public static void RegisterObjectEntity(IServerObject serverObject)
    {
      // this exist from an old hack related to save/load of UPnP Devices in DaPPLE
      // now it's just a call to the regular
      RegisterObject(serverObject);

      //long id = 100000;

      //// lock on Server Object Dictionary so we can prevent handing out duplicate IDs
      //lock (dummy)
      //{

      //  if (_NextServerID >= id)
      //  {
      //    // Get the next ID
      //    id = _NextServerID;

      //    // Increment the next ID
      //    _NextServerID++;
      //  }
      //  else
      //  {
      //    _NextServerID = id + 1;
      //  }
      //}

      //RegisterObject(serverObject, id);

      //Debug.WriteLine("Registered " + serverObject.ToString() + " with ID: " + id.ToString());
    }

    private static void RegisterObject(IServerObject serverObject, long id)
    {
      // Assign the Woz Object the next ID
      serverObject.ServerID = id;

      // Add the object to the registry using the ID
      _ServerObjects.Add(id, serverObject);
    }

    public static void RegisterObjectWithExisitingId(IServerObject serverObject)
    {
      try
      {
        if (_ServerObjects.ContainsKey(serverObject.ServerID))
        {
          _ServerObjects[serverObject.ServerID] = serverObject;
        }
        else
        {
          _ServerObjects.Add(serverObject.ServerID, serverObject);
          if (_NextServerID <= serverObject.ServerID)
          {
            _NextServerID = serverObject.ServerID + 1;
          }
        }
      }
      catch (Exception ex)
      {
        Debug.WriteLine("Object Registry: " + ex.ToString());
        if (serverObject != null)
        {
          Debug.WriteLine("               : Exception thrown during object addition ("
            + serverObject.ToString() + " with ID " + serverObject.ServerID.ToString() +
            "). That key probably already exisits");
        }
      }
    }

    public static bool ContainsObject(long ServerID)
    {
      return _ServerObjects.ContainsKey(ServerID);
    }

    public static IServerObject GetObject(long ServerID)
    {
      if (_ServerObjects.ContainsKey(ServerID))
      {
        return _ServerObjects[ServerID];
      }
      else
      {
        return null;
      }
    }

    public static void Clear()
    {
      _ServerObjects = new Dictionary<long, IServerObject>();

      _NextServerID = 0;

      dummy = new List<IServerObject>();
    }

    
  }
}
